
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.net.ssl.*;


public class Server implements Runnable {

	//The port we will listen on
	private int port;
	// A list of open connections
	private Set<ConnectionProcessor> connections = new HashSet<ConnectionProcessor>(); 
	// KeyStore for storing our public/private key pair
	private KeyStore clientKeyStore;  
	// KeyStore for storing the server's public key
	private KeyStore serverKeyStore;
	// Used to generate a SocketFactory
	private SSLContext sslContext; 
	static private SecureRandom secureRandom;
	private String myJksFile, myPwd, otherJksFile, otherPwd ;
	protected static XMLBuild xml;
	protected static String pot = "c:\\baza.xml";

  /**
   * Create a Server that listens on the given port.
   * Start the background listening thread
   */
  
	public Server(int port, String myJksFile, String myPwd, String otherJksFile, String otherPwd){  
		this.port = port;
		this.myJksFile = myJksFile;
		this.myPwd = myPwd;
		this.otherJksFile = otherJksFile;  
		this.otherPwd = otherPwd; 
		
		File f = new File(pot);
		xml = new XMLBuild(f);
		
		
		new Thread( this ).start();
	}

	private void setupClientKeyStore() throws GeneralSecurityException, IOException { 
		clientKeyStore = KeyStore.getInstance( "JKS" );
		clientKeyStore.load( new FileInputStream(otherJksFile), otherPwd.toCharArray() );
	}

	private void setupServerKeystore() throws GeneralSecurityException, IOException {
		serverKeyStore = KeyStore.getInstance( "JKS" );
		serverKeyStore.load( new FileInputStream( myJksFile ), myPwd.toCharArray() );
	}

	private void setupSSLContext() throws GeneralSecurityException, IOException {   
		TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );   
		tmf.init( clientKeyStore ); 
		KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );    
		kmf.init( serverKeyStore, myPwd.toCharArray() );  
		sslContext = SSLContext.getInstance( "TLS" );  
		sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), secureRandom );
	}

  /**
   * Background thread: accept new connections
   */
	public void run() {
		
		try {
			setupClientKeyStore();
			setupServerKeystore();
			setupSSLContext();
		
			SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
			SSLServerSocket ss = (SSLServerSocket)sf.createServerSocket( port );
			String[] cs ={"TLS_RSA_WITH_AES_128_CBC_SHA"};
			ss.setEnabledCipherSuites(cs);
		
			// Require client authorization
			ss.setNeedClientAuth( true );
		
			System.out.println( "Listening on port "+port+"..." );
		  
			while(true){	  
				Socket socket = ss.accept();
				System.out.println( "Got connection from " + socket );
				ConnectionProcessor cp = new ConnectionProcessor( this, socket );
				connections.add( cp );
			}
		} 
		catch(GeneralSecurityException gse){
			gse.printStackTrace();    
		}    
		catch(IOException ie) {
			ie.printStackTrace();    
		}	  
	}

	/**
	 * Remove a connection that has been closed from our set
	 * of open connections
	 */
	void removeConnection(ConnectionProcessor cp) {
		connections.remove(cp);
	}


	/**
	 * Create and start a Server.  The port number must
	 * be provided on the command line
	 */
	static public void main(String args[]) {
		
		if (args.length != 5){
			System.err.println( "Usage: java Server [port number]" );
			System.exit(1);
		}
		int port = Integer.parseInt(args[0]);

		System.out.println( "Wait while secure random numbers are initialized...." );
		secureRandom = new SecureRandom();
		secureRandom.nextInt();
		System.out.println( "Done." );
		new Server(port, args[1],args[2],args[3],args[4]);
	}
}
